#ifndef _PE_PARSER_H_
#define _PE_PARSER_H_

#include "file_structure.h"
#include "parser.h"
#include "pe.h"

#include <filesystem>
#include <fstream>
#include <optional>
#include <variant>
#include <vector>

namespace analyzer::windows
{

class pe_parser final : public parser
{
public:
    pe_parser(std::filesystem::path path);
    std::optional<file_structure> parse() override;

private:
    using image_header32_64 = std::variant<image_nt_header<x86>, image_nt_header<x64>>;

    bool contains_magic_bytes();
    void read_bitness();
    uint16_t read_image_header_position();
    void read_image_header(const uint16_t position);
    void read_section_headers(const uint16_t number_of_sections);
    void read_import_descriptors(const uint32_t import_table_position);
    std::string read_module_name(const image_section_header& table, const uint32_t name_address);
    std::size_t read_import_index(const uint32_t alignment, const uint32_t rva);
    std::vector<import_module> read_import_modules();

    std::filesystem::path path;
    std::ifstream file;
    uint8_t bitness{};
    size_t import_section_index{};
    image_header32_64 image_header;
    std::vector<image_section_header> section_headers;
    std::vector<image_import_descriptor> import_descriptors;
};

} // namespace analyzer::windows

#endif
